﻿using BCAMap.AMap;
using BCAMap.AMap.Dto;
using BCAMap.AMap.Enum;
using BCCommon;
using BCCommon.FreightEnums;
using BCCommon.NPinyin;
using BCData.Common.Area;
using BCDto.Sim.Admin.Admin;
using BCEntity.Common.Area;
using BCService.Common.Area;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static BCAMap.AMap.Dto.GeographyResponseDto;

namespace BCService.AMap
{
    public class AddressCodeInfoSynchronizeService : IAddressCodeInfoSynchronizeService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IAMapUtils iAMapUtils;
        private readonly IProvinceData provinceData;
        private readonly ICityData cityData;
        private readonly ICountyData countyData;

        public AddressCodeInfoSynchronizeService(IDatabaseContext databaseContext, 
            IAMapUtils iAMapUtils, IProvinceData provinceData, ICityData cityData, ICountyData countyData)
        {
            this.databaseContext = databaseContext;
            this.iAMapUtils = iAMapUtils;
            this.provinceData = provinceData;
            this.cityData = cityData;
            this.countyData = countyData;
        }

        public void Sync(AdminDto adminDto)
        {
            GeographyResponseDto dto = this.iAMapUtils.GetGeography(new GeographyRequestDto()
            {
                keywords = "中国",
                subdistrict = 3,
                Output = OutputType.JSON
            });
            if (int.Parse(dto.Status) == 1)
            {
                databaseContext.BeginTransaction();
                ParseGeographyInfo(dto.Districts.First().Districts, 0, adminDto);
                databaseContext.Commit();
            }
        }

        private void ParseGeographyInfo(IEnumerable<District> districts, long parentId, AdminDto adminDto)
        {
            foreach (District district in districts)
            {
                AppendData(district, parentId, adminDto);
            }
        }

        private void AppendData(District district, long parentId, AdminDto adminDto)
        {
            switch (district.Level)
            {
                case Level.province:
                    AddProvince(district, adminDto);
                    break;
                case Level.city:
                    AddCity(district, parentId, adminDto);
                    break;
                case Level.district:
                    AddCounty(district, parentId, adminDto);
                    break;
                default:
                    break;
            }
        }

        private void AddProvince(District district,AdminDto adminDto)
        {
            string[] center = district.Center.Split(',');
            double longitude = double.Parse(center[0]);
            double latitude = double.Parse(center[1]);
            ProvinceEntity entity = new ProvinceEntity()
            {
                ProvinceCode = district.Adcode,
                ProvinceName = district.Name,
                Longitude = longitude,
                Latitude = latitude,
                IsEnabled = true,
                Editer = adminDto.FullName
            };

            if (!provinceData.CheckProvinceExistsByCode(entity.ProvinceCode))
            {
                if (this.provinceData.Add(entity))
                {
                    var provinceEntity = this.provinceData.GetProvince(entity.ProvinceCode);
                    if (district.Districts.Any())
                    {
                        ParseGeographyInfo(district.Districts, provinceEntity.ProvinceId, adminDto);
                    }
                }
            }
        }

        private void AddCity(District district, long parentId, AdminDto adminDto)
        {
            string[] center = district.Center.Split(',');
            double longitude = double.Parse(center[0]);
            double latitude = double.Parse(center[1]);
            ProvinceEntity provinceEntity = this.provinceData.GetProvince(parentId);
            CityEntity entity = new CityEntity()
            {
                CityInitials = Pinyin.GetInitials(district.Name),
                ProvinceId = provinceEntity.ProvinceId,
                ProvinceCode = provinceEntity.ProvinceCode,
                ProvinceName = provinceEntity.ProvinceName,
                CityCode = district.Adcode,
                CityName = district.Name,
                CapitalCity = false,
                Longitude = longitude,
                Latitude = latitude,
                IsEnabled = true,
                Editer = adminDto.FullName
            };

            if (!cityData.CheckExistsByCode(entity.CityCode))
            {
                if (this.cityData.Add(entity))
                {
                    var cityEntity = this.cityData.GetCity(entity.CityCode);
                    if (district.Districts.Any())
                    {
                        ParseGeographyInfo(district.Districts, cityEntity.CityId, adminDto);
                    }
                }
            }
        }

        private void AddCounty(District district, long parentId, AdminDto adminDto)
        {
            string[] center = district.Center.Split(',');
            double longitude = double.Parse(center[0]);
            double latitude = double.Parse(center[1]);
            CityEntity cityEntity = this.cityData.GetCity(parentId);
            CountyEntity entity = new CountyEntity()
            {
                ProvinceId = cityEntity.ProvinceId,
                ProvinceCode = cityEntity.ProvinceCode,
                ProvinceName = cityEntity.ProvinceName,
                CityId = cityEntity.CityId,
                CityCode = cityEntity.CityCode,
                CityName = cityEntity.CityName,
                CountyCode = district.Adcode,
                CountyName = district.Name,
                CountyEasyBackGoods = EasyBackGoodsType.Normal,
                CapitalCity = false,
                Longitude = longitude,
                Latitude = latitude,
                IsEnabled = true,
                Editer = adminDto.FullName
            };

            if (!countyData.CheckExistsByCode(entity.CountyCode))
            {
                if (this.countyData.Add(entity))
                {
                    var countyEntity = this.countyData.GetCounty(entity.CountyCode);
                }
            }
        }
    }
}
